#include"Common.h"
#include"ThreadCache.h"
#include"PageCache.h"
#include"Objectpool.h"
static void* ConcurrentAlloc(size_t size)
{   
    if(size > NSPANLIST)
    {
        size_t Alignsize = Sizeclass::_Roundup(size,NSPANLIST);
        size_t kpage = Alignsize >> PAGE_SHIFT;

        PageCache::GetInstance()->_PageMTX.lock();
        Span* span = PageCache::GetInstance()->NewSpan(kpage);
        span->_objsize = size;
        PageCache::GetInstance()->_PageMTX.unlock();

        void* ptr = (void*)(span->Page_Id << NSPANLIST);
        return ptr;
    }
    else
    {
        //通过TLS  每个线程无锁地获取自己的专属ThreadCache对象
        if(pTLSThreadCache == nullptr)
        {
            static Objectpool<ThreadCache> tcPool;
            //pTLSThreadCache = new ThreadCache;
            pTLSThreadCache = tcPool.New();
        }
        return pTLSThreadCache->Allocate(size);
    }
    
}

//释放ThreadCache对象
static void ConcurrentFree(void* ptr)
{   
    Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr); 
    size_t size = span->_objsize;
    
    if(size > MAX_BYTES)
    {
        Page_Id id = (Page_Id)ptr >> NSPANLIST;
        Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);

        PageCache::GetInstance()->_PageMTX.lock();
        PageCache::GetInstance()->ReleaseSpanToPageCache(span);
        PageCache::GetInstance()->_PageMTX.unlock();
    }
    else
    {
        assert(pTLSThreadCache);
        pTLSThreadCache->Deallocate(ptr,size);
    }
    
}   